import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.StringJoiner;

/**
 * 泛型擦除
 *
 * @author <a href="mailto:mojo_jj@163.com">Mojo</a>
 */
public class GenericityErasure {
    private String name;
    private Double sal;
    private MyDate myDate;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getSal() {
        return sal;
    }

    public void setSal(Double sal) {
        this.sal = sal;
    }

    public MyDate getMyDate() {
        return myDate;
    }

    public void setMyDate(MyDate myDate) {
        this.myDate = myDate;
    }

    public GenericityErasure(String name, Double sal, MyDate myDate) {
        this.name = name;
        this.sal = sal;
        this.myDate = myDate;
    }

    @Override
    public String toString() {
        return new StringJoiner(", ", GenericityErasure.class.getSimpleName() + "[", "]")
                .add("name='" + name + "'")
                .add("sal=" + sal)
                .add("myDate=" + myDate)
                .toString();
    }

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(1);  //这样调用 add 方法只能存储整形，因为泛型类型的实例为 Integer
        //通过反射证明可以往list add其他类型的元素，证明了泛型可擦除
        list.getClass().getMethod("add", Object.class).invoke(list, "asd");

        for (Integer integer : list) {
            System.out.println(integer);
        }
        System.out.println("=============================================");
        ArrayList l = new ArrayList<String>();
        l.add(1);//编译通过
        l.add("1");//编译通过
        //运行报错，ClassCastException
        for (Object o : l) {
            System.out.println(o);
        }
        ArrayList<String> l1 = new ArrayList<>();
        //l1.add(1);编译报错
        // l和l1证明了泛型是在编译器做类型检查的，然后再做类型擦除。同时真正涉及类型检查的是引用而不是new ArrayList()
    }
}
